package com.ruoyi.tcp.client.pool;
import com.ruoyi.tcp.client.ClientCustomerHandler;
import com.ruoyi.tcp.messager.CustomerMessageDecoder;
import com.ruoyi.tcp.messager.CustomerMessageEncoder;
import io.netty.bootstrap.Bootstrap;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.timeout.IdleStateHandler;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.Semaphore;

public class TcpConnectionPool {

    private final Map<String, Channel> connections = new ConcurrentHashMap<>();
    private final Semaphore semaphore;
    private final EventLoopGroup group = new NioEventLoopGroup();
    private final Bootstrap bootstrap = new Bootstrap();

    public TcpConnectionPool(int maxConnections) {
        this.semaphore = new Semaphore(maxConnections);
        this.bootstrap.group(group)
                .channel(NioSocketChannel.class)
                .handler(new ChannelInitializer<SocketChannel>() {
                    @Override
                    protected void initChannel(SocketChannel socketChannel) throws Exception {
                        ChannelPipeline pipeline = socketChannel.pipeline();
//                        pipeline.addLast(new IdleStateHandler(0,30,0));
                        pipeline.addLast(new CustomerMessageDecoder());
                        pipeline.addLast(new CustomerMessageEncoder());
                        pipeline.addLast(new ClientCustomerHandler());
                    }
                });
    }

    public Channel getConnection(String key, String host, int port) throws InterruptedException {
        semaphore.acquire();
        return connections.computeIfAbsent(key, k -> {
            try {
                ChannelFuture future = bootstrap.connect(host, port).sync();
                return future.channel();
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        });
    }

    public void releaseConnection(String key, Channel channel) {
        connections.remove(key, channel);
        channel.close();
        semaphore.release();
    }

    // 关闭所有连接
    public void shutdown() {
        group.shutdownGracefully();
    }
}

